//  IDVI 1.0 source copyright 1996 Garth A. Dickie
//
//  This source is free for non-commercial use.  No warranty, etc.
//  Please acknowledge reuse by including the line:
//
//  "Based in part on IDVI 1.0 source copyright 1996 Garth A. Dickie"
//
//  in your documentation and source code.  For commercial use or
//  distribution, please contact the author.  Please also send
//  questions, comments, bug reports, or fixes.
//
//  Best Regards,
//  Garth A. Dickie
//  dickie@elastic.avid.com

package ibook.v10.idvi.font;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.image.MemoryImageSource;

import ibook.v10.idvi.*;

/**
 * Internal representation of a single character.
 * @see PKFont
 * @version 1.02 22 Jan 1996
 * @author Garth A. Dickie
 */
public abstract class DVICharacter {
    public int          tfmWidth;
    public int          width;
    public int          height;
    public int          xOffset;
    public int          yOffset;

    //  decodeBits( ) should initialize the byte array bits.  When decodeBits( ) is called,
    //  bits will be null.

    protected byte[ ]   bits;

    protected abstract void decodeBits( );




    public byte[ ] getUnscaledBits( ) {
        decodeBits( );
        return bits;
    }

    public byte[ ] getScaledBits( int scale, int scaledWidth, int scaledHeight ) {
        decodeBits( );

        byte[ ] result = new byte[ scaledWidth * scaledHeight ];

        int xPadding = xOffset > 0 ? scale - xOffset % scale : - xOffset % scale;
        int yPadding = yOffset > 0 ? scale - yOffset % scale : - yOffset % scale;

        for( int row = 0; row < height; ++ row ) {
            int rowIndex = row * width;
            int scaledRowIndex = (( row + yPadding ) / scale ) * scaledWidth;
            for( int column = 0; column < width; ++ column )
                if( bits[ rowIndex + column ] != 0 )
                    result[ scaledRowIndex + ( column + xPadding ) / scale ] += 1;
        }

        //  debugging output:
        //  for( int scaledRow = 0; scaledRow < scaledHeight; ++ scaledRow ) {
        //      for( int scaledColumn = 0; scaledColumn < scaledWidth; ++ scaledColumn )
        //          System.out.print( result[ scaledRow * scaledWidth + scaledColumn ] != 0 ? '#' : ' ' );
        //      
        //      System.out.println( );
        //  }

        return result;
    }

    final public int getScaledWidth( int scale ) {
        return (( xOffset > 0 ? scale - xOffset % scale : - xOffset % scale) + width + scale - 1 ) / scale;
    }

    final public int getScaledHeight( int scale ) {
        return (( yOffset > 0 ? scale - yOffset % scale : - yOffset % scale) + height + scale - 1 ) / scale;
    }

    final public int getScaledXOffset( int scale ) {
        return (( xOffset > 0 ? scale - xOffset % scale : - xOffset % scale) + xOffset ) / scale;
    }

    final public int getScaledYOffset( int scale ) {
        return (( yOffset > 0 ? scale - yOffset % scale : - yOffset % scale) + yOffset ) / scale;
    }




    final public int getTFMWidth( ) {
        return tfmWidth;
    }

    final public int getXOffset( ) {
        return xOffset;
    }

    final public int getYOffset( ) {
        return yOffset;
    }

    final public int getWidth( ) {
        return width;
    }

    final public int getHeight( ) {
        return height;
    }
}
